var Promise = require('es6-promise.js')
var app = getApp();
/**
 * BU01Reader构造
 */
function BU01Reader(){

  /**
   * 使用微信蓝牙写数据
   */
  var writeBLECharacteristicValue = (buffer) => new Promise((resolve, reject) => {
    wx.writeBLECharacteristicValue({
      deviceId: app.globalData.connectedDeviceId,
      serviceId: app.globalData.serviceId,
      characteristicId: app.globalData.writeCharacteristicId,
      value: buffer,
      success: resolve,
      fail: reject,
    })
  })

  var writeData = (buffer) => writeBLECharacteristicValue(buffer)
    .then(res => {
      console.log('--> 发送characteristicValue成功')
  }).catch(err => {
    reset()
    return Promise.reject(-101)
  })


  //以下为数据发送与处理

  var analysis
  var newCmd = true
  var data
  var dataLength = 0

  var inventoryRecord = ''
  var inventoryResult = []

  /**
   * 发送数据并注册解析
   */
  var send = (cmd) => {
    if(analysis != undefined){
      return Promise.reject(-202)
    }
    //避免无间隔连续发送指令
    analysis = ''
    var cmdBytes = hexStrToBytes(cmd)
    let buffer = new ArrayBuffer(cmdBytes.length)
    let dataView = new DataView(buffer)
    for (let i = 0; i < dataView.byteLength; i++) {
      dataView.setUint8(i, cmdBytes[i])
    }
    console.log('--> ' + cmd)
    var promise = Promise.resolve()
    //安卓系统需要分包(20字节)
    for (let i = 0; i < cmdBytes.length; i += 20) {
      promise = promise.then(() => {
        return writeData(buffer.slice(i, i + 20 > cmdBytes.length ? cmdBytes.length : i + 20))
      })
    }
    // if (getApp().globalData.platform == 'android') {
     
    // }
    // else if (getApp().globalData.platform == 'ios') {
    //   promise = promise.then(() => {
    //     return writeData(buffer)
    //   })
    // }
    // else {
    //   //不知道mac机是否与ios一样
    //   promise = promise.then(() => {
    //     return writeData(buffer)
    //   })
    // }
    //注册解析数据包，当onBleCharacteristicValue事件触发时将调用analysis(receive)
    return promise.then(() => new Promise((resolve, reject) => {
      var isReceive = false
      var onceReply = ''
      //清点结果解析
      analysis = (receive) => {
        isReceive = true
        var dataLength = parseInt(receive.substring(2, 4), 16)
        if ((dataLength+2)*2 == receive.length){
          var result = receive.substr(4);
          reset()
          return resolve(result)
        }else　{
          reset()
          return reject(-301)
        }
        
      }
        
      setTimeout(() => {
        if (!isReceive) {
          reset()
          return reject(-301)
          }
        }, 60000)
    }))
  }

  var reset = () => {
    newCmd = true
    analysis = undefined
    inventoryRecord = ''
    inventoryResult = []
  }

  //以下为命令相关

  /**
   * 命令包头
   */
  var cmdHead = 'BB'

  /**
   * 命令发送
   */
  var cmdSend = '00'

  /**
   * 命令接收
   */
  var cmdReceive = '01'

  /**
   * UII结束标志
   */
  var cmdUIIFinish = '03'

  /**
   * 命令类型
   */

  var command = {
    Init: 'A0',
    Sale: 'A1',
    Recharge: 'A3',
    Replenishment: 'A2'
  }

  /**
   * 命令生成
   */

  var createCmd = (cmdType, data) => {
    data = data || ''
    var dataLengthHex = data.length.toString(16).toUpperCase();
    if(cmdType == command.Init){
      return cmdType +"0100";
    }else{
      return cmdType + hexStrTo2Digits(dataLengthHex) + strToHexStr(data)
    }
  }

  // 以下为对外蓝牙接口

  /**
   * 蓝牙接收数据监听
   */
  this.monitor = () => {
    wx.onBLECharacteristicValueChange(characteristic => {
      let buffer = characteristic.value
      let dataView = new DataView(buffer)
      var receive = ''
      console.log('<-- 接收字节长度：' + dataView.byteLength)
      for (let i = 0; i < dataView.byteLength; i++) {
        console.log(dataView.getUint8(i));
        var d = dataView.getUint8(i).toString(16).toUpperCase();
        receive += hexStrTo2Digits(d)
      }
      console.log('<-- ', receive)
      setTimeout(function(){
        if (analysis == undefined) {
          console.log('<-- analysis undefined')
        } else if (analysis == '') {
          console.log('<-- 还未设置好数据处理')
        } else {
          analysis(receive)
        }
      },1000)
    })
  }

  /**
   * 获取读写器版本
   */
  this.getReaderVersion = () => send(createCmd(command.GetVersion, jointHexStr('05'))).then(res => {
    return Promise.resolve(hexStrToChar(res))
  })

  this.sendInitCmd = () => send(createCmd(command.Init, 0x0)).then(res => {
    return Promise.resolve(hexStrToChar(res.substring(12,24)))
  })
  this.sendSaleCmd = (data) => send(createCmd(command.Sale, data)).then(res => {
    return Promise.resolve(hexStrToChar(res))
  })
  this.sendRechargeCmd = (data) => send(createCmd(command.Recharge, data)).then(res => {
    return Promise.resolve(hexStrToChar(res))
  })
  this.sendReplenishmentCmd = (data) => send(createCmd(command.Replenishment, data)).then(res => {
    return Promise.resolve(hexStrToChar(res))
  })

}

/**
 * 计算tag rssi
 */
function calRssi(rssiStr) {
  var tag_rssi = 0.0
  var rssi_i = 0
  var rssi_q = 0
  var gain_i = 0
  var gain_q = 0
  var rfin_i = 0.0
  var rfin_q = 0.0

  rssi_i = parseInt(rssiStr.substr(0, 2), 16) & 0xFF
  rssi_q = parseInt(rssiStr.substr(2, 2), 16) & 0xFF
  gain_i = parseInt(rssiStr.substr(4, 2), 16) & 0xFF
  gain_q = parseInt(rssiStr.substr(6, 2), 16) & 0xFF

  rfin_i = 20 * Math.log10(rssi_i) - gain_i - 33 - 30
  rfin_q = 20 * Math.log10(rssi_q) - gain_q - 33 - 30

  rfin_i = Math.pow(10, rfin_i / 20)
  rfin_q = Math.pow(10, rfin_q / 20)

  tag_rssi = Math.sqrt(Math.pow(rfin_i, 2) + Math.pow(rfin_q, 2))
  tag_rssi = 20 * Math.log10(tag_rssi)
  tag_rssi = tag_rssi.toFixed(1)

  return tag_rssi
}

/**
 * 解析UII
 */
var parseUII = (uiiArr) => {
  var epcs = uiiArr.map((element, index, arr) => {
    element = element || ''
    return {
      pc: element.substring(0, 4),
      epc: element.substring(4, element.length - 8),
      epcWithSpace: element.substring(4, element.length - 8).replace(/(.{8})/g, '$1 '),
      rssi: calRssi(element.substring(element.length - 8))
    }
  })
  return epcs
}

/**
 * 计算功率，hex --> int
 */
var calPower = (hexStr) => {
  var powerStr = hexStr.substr(0, 4)
  return Math.round(parseInt(powerStr, 16) / 10.0)
}

/**
 * 字符串拼接
 */
var jointHexStr = function () {
  var hexStr = ''
  Array.prototype.forEach.call(arguments, (elem, i) => {
    elem = elem || ''
    hexStr += trimAllSpace(elem)
  })
  return hexStr
}

/**
 * 16进制字符串 --> 字符 ASCII
 */
var hexStrToChar = (data) => {
  var converted = ''
  for (let i = 0; i < data.length / 2; i++) {
    converted += String.fromCharCode(parseInt(data.substring(i * 2, (i + 1) * 2), 16))
  }
  return converted
}

/**
 * 字符 --> 16进制字符串
 */
var strToHexStr = (str) => {
  str = str || ''
  var hexStr = ''
  for (let i = 0; i < str.length; i++) {
    hexStr += str.codePointAt(i).toString(16)
  }
  return hexStr
}

/**
 * 16进制字符串 --> byte array
 */
var hexStrToBytes = (str) => {
  str = str || ''
  for (var result = [], c = 0; c < str.length; c += 2) {
    result.push(parseInt(str.substr(c, 2), 16))
  }
  return result
}

/**
 * 8位 --> 16进制字符串
 */
var uint8ToHexStr = (data) => {
  data = data || ''
  return ('00' + data.toString(16).toUpperCase()).slice(-2)
}

/**
 * 16位 --> 16进制字符串
 */
var uint16ToHexStr = (data) => {
  data = data || ''
  return ('0000' + data.toString(16).toUpperCase()).slice(-4)
}

/**
 * 2位16进制字符串补0
 */
var hexStrTo2Digits = (data) => {
  data = data || ''
  return ('00' + data.toUpperCase()).slice(-2)
}

/**
 * 4位16进制字符串补0
 */
var hexStrTo4Digits = (data) => {
  data = data || ''
  return ('0000' + data.toUpperCase()).slice(-4)
}

/**
 * 10进制序列号 --> 4字节16进制
 */
var handleSerialNumber = (no) => {
  no = trimAllSpace(no) || ''
  return  Number(no).toString(16).toUpperCase()
}

/**
 * 去掉字符串中所有的空格
 */
var trimAllSpace = (str) => {
  return str.replace(/ /g, '')
}


module.exports = {
  BU01Reader: BU01Reader,
  trimAllSpace: trimAllSpace
}
